home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 July
/
Macworld (1999-07).dmg
/
Shareware World
/
Info
/
For Developers
/
Mops 3.4.sea
/
Mops source
/
Module source
/
callsMod.txt
< prev
next >
Wrap
Text File
|
1998-05-30
|
9KB
|
377 lines
room 750000 u<
[IF]
cr .( not enough dic room to compile callsMod!) cr ABORT
[THEN]
false constant debug?
file INPF
: #ALIGN4 \ ( n -- n' )
3 + $ fffffffc and ;
true -> case_in_names?
: macConstant
[ FALSE -> CASE_IN_NAMES? ]
>in @
defined?
IF ['] inpf u> IF 2drop EXIT THEN
ELSE drop
THEN
>in !
constant
;
: [IF] drop ;
: [ELSE] ;
: [THEN] ;
: [ELIF] drop ;
true -> case_in_names?
: macDefined? DEFINED? NIP ;
: macStruct MWORD DROP ;
: macUnion MWORD DROP ;
: macField DROP MWORD DROP ;
: macFiller 2DROP ;
: macEnd-struct 2DROP ;
: macEnd-union 2DROP ;
: macSynonym MWORD DROP MWORD DROP ;
: and AND ;
: or OR ;
: xor XOR ;
: lshift LSHIFT ;
: rshift RSHIFT ;
: negate NEGATE ;
: 'type POSTPONE 'TYPE ; IMMEDIATE
FALSE -> CASE_IN_NAMES?
string temp
: READ_INLINE { \ loc svd svCaseFlg -- }
case_in_names? -> svCaseFlg
false -> case_in_names?
clear: temp
BEGIN
>in @ src-len >=
IF svCaseFlg -> case_in_names? EXIT
THEN
hex mword number decimal
pad w! pad 2 add: temp
AGAIN ;
false value register_based?
0 value ^hndlr
(* For 68k parms, a parm or result might be in a register. If so,
our parm info will have this format:
byte 0 0
byte 1 $80 + reg number
byte 2 0
byte 3 length in bytes
The reg numbers, as defined in MixedMode.h, are:
0 d0
1 d1
2 d2
3 d3
4 a0
5 a1
6 a2
7 a3
8 d4
9 d5
A d6
B d7
C a4
D a5
E a6
We have to return a 1-byte result, so we use this format:
bit
0 1 means this is a register parm/result
1-3 length
4-7 reg code
This byte is passed to Handlers which compiles the right register
pushes and/or pops.
*)
: 68k_parm_adjust { parm parm# parm? -- parm' }
parm -1 =
NIF
parm $ ffff0000 and
IF \ it's a register parm
true -> register_based?
$ D001 ^hndlr w!
parm dup 16 >> \ reg code
swap 3 and \ length
4 << or EXIT
THEN
THEN
parm? \ parm or result?
IF \ parm
register_based?
IF ." warning - non-reg parm in reg-based call "
latest name> .id cr
THEN
parm
\ dup 1 and + \ &&& don't round length any more
ELSE \ result
parm IF
register_based?
IF ." warning - non-reg result in reg-based call "
latest name> .id cr
THEN
THEN
parm \ for results, we don't round so call
THEN \ windup gets done properly.
;
true -> case_in_names?
: macExtern
[ FALSE -> CASE_IN_NAMES? ]
( result-info parm-info #parms )
{ \ #parms #cells #fparms #fres mask ^PPCinfo ^68kInfo -- }
0 -> #cells 0 -> #fparms false -> register_based?
0 -> #fres 0 -> mask
\ true -> case_in_names?
>in @
defined?
IF ['] inpf u>
IF drop \ drop >in - now TOS is # parms
-1 DO 2drop LOOP \ drop parm info, also result info
0 -> src-len \ skip 68k inline code sequence
\ false -> case_in_names?
EXIT
THEN
ELSE drop
THEN
>in !
create \ create the new dic entry (case sensitive)
\ false -> case_in_names?
DP 2- -> ^hndlr
$ D000 ^hndlr w! \ dummy "handler code"
DP -> ^PPCinfo 0 , 0 w, \ leave space for PPC info
\ #parms
dup -> #parms c, \ store # parms for 68k
DP -> ^68kInfo
#parms
IF pad #parms n, \ reserve space for rest of 68k parm info
#parms
FOR
\ #bytes in next PPC parm - convert to #cells and accumulate. If
\ the $ 1000 bit is set, that means it's floating point - in that
\ case we count up the number of floating parms (these have to
\ be put in the FPRs for the call), and set the corresponding mask
\ bit so that the corresponding GPRs will get a dummy value. This
\ calling convention is a bit crazy, but we're stuck with it.
\ Remember as the numbers have been pushed onto the stack, we're
\ going from the last parm backwards. So i in this FOR loop gives
\ us the real parm# starting from zero.
dup $ 1000 and
IF \ it's floating
1 ++> #fparms
$ FFF and dup 4 >
IF mask 2 >> $ C000 or -> mask \ mask 2 dummy GPRs here
ELSE mask 1 >> $ 8000 or -> mask \ single float - mask 1 GPR
THEN
ELSE
mask 1 >> -> mask \ normal GPR cell - no mask bit
THEN
3 + 2 >> ++> #cells
\ 68k parm info
i true 68k_parm_adjust \ check if reg-based and take care of it
^68kInfo i + c! \ store in right order in 68k info
NEXT
THEN
#cells ^PPCinfo c! \ store # PPC parm cells at ^PPCinfo
\ ( #68k-res-bytes #PPC-res-bytes )
dup $ 1000 and
IF \ PPC result is floating - so no integer result
1 -> #fres drop 0
ELSE \ otherwise there's no floating result
3 + 2 >>
THEN ^PPCinfo 1+ c! \ store # PPC integer result cells at ^PPCinfo+1
#fparms ^PPCinfo 2+ c! \ and # PPC FP parms at ^PPCinfo+2
#fres ^PPCinfo 3 + c! \ and # PPC FP results at ^PPCinfo+3
\ (must be 0 or 1)
mask ^PPCinfo 4+ w!
0 false 68k_parm_adjust c, \ store 68k info. We don't
\ round here since we have to know whether
\ and by how much to adjust by at the end
\ of the call.
align-dp
read_inline
reset: temp len: temp w, all: temp n,
0 -> src-len \ on the PPC we ignore the 68k inline code sequence
;
: FIND_IN_CALLSMOD \ ( s255 \ svCaseFlg -- cfa true | -- s255 false )
find: callsMod
;
: myHeader
PPC? IF ppc_header ELSE header THEN ;
: KONST { \ svCaseFlg -- konst }
case_in_names? -> svCaseFlg
true -> case_in_names?
['] find_in_callsMod -> extraFind
'
svCaseFlg -> case_in_names?
0 -> extraFind
dup 2- w@x -4 <> abort" not a konst!"
@ postpone lit
; immediate
: $>KONST { addr len \ svCaseFlg -- konst }
case_in_names? -> svCaseFlg
true -> case_in_names?
['] find_in_callsMod -> extraFind
addr len sFind
svCaseFlg -> case_in_names?
0 -> extraFind
NIF abort" konst not defined" THEN
dup 2- w@x -4 <> abort" not a konst!"
@
;
(*
syscall bloggs defines "bloggs" as an system call (from the InterfaceLib
library).
In a definition we just put "bloggs" and it compiles a call to bloggs. We
resolve the symbol via a FindSymbol call, the first time it's called (see
get_transfer_vector in Setup - a call is compiled to there as part of the
external call sequence, compiled by call_extern in cg5).
*)
: SYSCALL { \ svCaseFlg sv-in addr #parms
#parm_cells #fparms #res_cells #fres mask
len ^len-byte name_len -- }
?exec
>in @ -> sv-in
\ first, is it actually a known call?
case_in_names? -> svCaseFlg
true -> case_in_names?
['] find_in_callsMod -> extraFind
mword find NIF 150 die THEN \ "can't find call for this name"
0 -> extraFind svCaseFlg -> case_in_names?
-> addr
addr 2- w@
dup 1 and -> register_based?
-2 and $ D000 <> abort" not a call!"
\ now, if we've already defined it as a sysCall, and it's currently
\ FINDable, we don't need to define it again here.
sv-in >in !
defined?
IF 2- w@x
CASE[ -120 ], [ -122 ]=> PPC? 0EXIT
[ $ BF01 ]=> PPC? ?EXIT
DEFAULT=> drop
]CASE
ELSE
drop
THEN
sv-in >in !
PPC?
IF myHeader $ BF01 codeW, \ $BF01 = handler code for sysCall
addr c@ -> #parm_cells
addr 1+ c@ -> #res_cells
addr 2+ c@ -> #fparms
addr 3 + c@ -> #fres
addr 4+ w@ -> mask
#parm_cells codeC, \ 1 byte # parm cells
#res_cells codeC, \ 1 byte # result cells
#fparms codeC, \ 1 byte # FP parms (in FPRs)
#fres codeC, \ 1 byte # FP results (in FPRs)
mask codeW,
DP nilP , \ put nilP in data area - means not resolved yet
" relocCode,x" evaluate \ not defined till cg6
0 code, \ for EXTERNs, lib addr goes here. For SYSCALL,
\ we put zero. (This is different to 68k)
addr >name n>count dup -> name_len
CDP place
name_len 2+ #align4 ++> CDP
ELSE
header
register_based? IF -122 ELSE -120 THEN
w, \ sysCall_h handler for 68k
6 ++> addr \ look at 68k parm info
addr c@ -> #parms
DP -> ^len-byte 0 c, \ total length of call info will go here
#parms c,
1 ++> addr
#parms 1+ FOR \ add 1 since we're including the result byte
addr c@ c, 1 ++> addr
NEXT
addr 1 and ++> addr
1 or> DP \ put DP to odd bdry since we'll be omitting
\ the length byte
addr length \ ( addr len ) for inline code
dup NIF 152 die THEN \ "not a real call" - since no inline code
n, \ move inline code over
DP ^len-byte - 1-
^len-byte c! \ and store length of call info (excluding length byte)
THEN
;
new: temp
cr
cr .( Note: loading this next file will take quite a while.)
cr .( A coffee break would be a good idea.) cr
true -> case_in_names?
// xcalls
FALSE -> CASE_IN_NAMES?
release: temp
cr .( Dic room at end of compiling callsMod: ) room . cr